library ieee ;
use ieee.std_logic_1164.all ;
use ieee.numeric_std.all ;


library lib_ExpoRNS ;


-- Fichier de test de la MMU


------------------------------

entity TEST_MMU is
  port(
	signal a_real : out unsigned(31 downto 0) ;
	signal b_real : out unsigned(31 downto 0) ;
	signal c_real : out unsigned(31 downto 0) 
    );
end TEST_MMU ;


------------------------------

architecture arch_test_MMU of TEST_MMU is
	
	-- Définition du composant principal
	
	component Mult_Montg_Unit is
	generic(
		Z : positive range 1 to 256 := 16 ;	-- Nombre de bits du module
		N : positive := 255 ;	-- Vecteur de base utilisé
		R : positive := 256 ;	-- Plus proche puissance de 2 de N par valeur supérieure
		k : positive := 1 	-- Constante nécessaire au calcul
	) ;
	port (
		a : in std_logic_vector(Z-1 downto 0) ;	-- Entrée 1 multiplicateur (domaine de Montgomery)
		b : in std_logic_vector(Z-1 downto 0) ;	-- Entrée 2 multiplicateur (domaine de Montgomery)
		is_active : in std_logic ;		-- La MMU doit-elle fonctionner?
		
		c : out std_logic_vector(Z-1 downto 0) ;	-- Sortie du multiplicateur (domaine de Montgomery)
		is_ready : out std_logic ;		-- La MMU est-elle prête à fonctionner?
		is_end : out std_logic		-- La MMU a-t-elle fini?
	) ;
	end component;
	
	
	-- Définition des signaux à utiliser 
	
	signal a : std_logic_vector(16-1 downto 0) := (others => '0') ;
	signal b : std_logic_vector(16-1 downto 0) := (others => '0') ;
	signal is_active : std_logic := '1' ;
	
	signal c : std_logic_vector(16-1 downto 0) ;
	signal is_ready : std_logic ;
	signal is_end : std_logic ;
	
	-- signal a_real : unsigned(31 downto 0) := (others => '0') ;
	-- signal b_real : unsigned(31 downto 0) := (others => '0') ;
	-- signal c_real : unsigned(31 downto 0) := (others => '0') ;


	

        --signal R : positive := 65536;
        --signal N : positive := 65535;

        signal R : positive := 256;
        signal N : positive := 255;
	
begin
	
	MMU : Mult_Montg_Unit port map(
		a => a ,        
		b => b ,
		is_active => is_active ,
		
		c => c ,
		is_ready => is_ready ,
		is_end => is_end 
	) ;
	
	
	values_a : process
	begin
		a <= "0000000000000001";
		wait for 50 ns ;
		a <= "0000000100010001";
		wait for 100 ns ;
		a <= "0000000000110001"; 
		
		
	end process ;
	
	
	values_b : process
	begin
		b <= "0000000000000001";
		wait for 100 ns ;
		b <= "0001111111000001";
		wait for 100 ns ;
		b <= "0000111100101001";
		
	end process ;
	
	a_real <= ( unsigned(a) * R ) mod N ;
	
	b_real <= ( unsigned(b) * R ) mod N ;
	
	c_real <= ( unsigned(c) * R ) mod N ;
	
end ;
